/**
 *
 */
package a3middlewareapi;

import it.polimi.leo.a3.A3Node;
import it.polimi.leo.jg.JGFactory;
import it.polimi.leo.jg.JGGroup;
import it.polimi.leo.jg.JGMessage;
import it.polimi.leo.jg.JGNode;
import it.polimi.leo.mw.JoinGroupException;
import it.polimi.leo.utils.TeaminatableThread;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jgroups.Address;
import org.jgroups.JChannel;
import org.jgroups.Message;
import org.jgroups.ReceiverAdapter;

/**
 * @author Lev
 *
 */
public class Main {

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        //new Main().testA3();
        new Main().testAddr();
        //new Main().testJGmw();
        //new Main().testJChannel();
    }
    void testA3(){
        try {
            JGFactory fac = new JGFactory();
            A3Node[] nodes = {
                new A3Node("node0", fac, 5, new JGGroup("group1"), new JGGroup("group2") ),
                new A3Node("node1", fac, 4, new JGGroup("group1") ),

            };
            for (A3Node a3Node : nodes) {
                a3Node.start();
            }
            nodes[0].sendMsg(fac.getIMiddlewareMessageFactory().
                    createBecomeAsuperviserMsg(new JGGroup("group1")),
                    "group1", new JGNode("node1") );
            

            Thread.sleep(5000);
            for (A3Node a3Node : nodes) {
                a3Node.terminate();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JoinGroupException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    void testAddr(){
        try {
            JChannel channel = new JChannel();
            channel.connect("Cl1");
            System.out.println("1:" + channel.getAddressAsString());
            for( Address a : channel.getView()){
                System.out.println("2:" + a.toString());
            }
            channel.close();
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
    void testJGmw(){
        try {
            TeaminatableThread t = new TeaminatableThread(){
                @Override
                public void run(){
                    try {
                        JGNode n2 = new JGNode();
                        n2.joinGroup(new JGGroup("group1"));
                        while(this.isNotTerminate()){
                            //Thread.yield();
                            this.sleep(2000);
                            System.out.println("msg: " + n2.receiveMsg().getPayLoad());
                        }
                        System.out.println("Bye");
                        n2.leaveGroup();
                    } catch (Exception ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            };
            t.start();
            
            JGNode n1 = new JGNode();
            n1.joinGroup(new JGGroup("group1"));
            n1.sendMsg(new JGMessage("test"));
            Thread.sleep(1000);
            n1.leaveGroup();
            t.terminate();
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    void testJChannel() throws Exception {
        JChannel channel = new JChannel(); //"/home/bela/udp.xml"
        //channel.setReceiver(new )

        Thread t = new Thread() {
            private volatile boolean running = true;
            public void terminate() {
                running = false;
            }
            public void run() {
                try {
                    JChannel ch = new JChannel();
                    ch.connect("MyCluster");
                    ch.setReceiver(new ReceiverAdapter() {
                        @Override
                        public void receive(Message msg) {
                            System.out.println("1)received msg in new thread " + msg.getSrc() + ": " + msg.getObject());
                        }
                    });
                    while(running){
                        //Thread.currentThread().sleep(1000);
                    }
                    ch.close();
                } catch (Exception ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
        t.start();

        //Thread.sleep(1000);
        channel.setReceiver(new ReceiverAdapter() {
            public void receive(Message msg) {
                System.out.println("2)received msg from " + msg.getSrc() + ": "
                        + msg.getObject());
            }
        });
        try {
            channel.connect("MyCluster");
            channel.send(new Message(null, null, "hello world"));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Thread.sleep(1000);
        t.getClass().getMethod("terminate").invoke(t);  //stop unnamed class
        channel.close();
    }
}
